package com.yanfan.energy.service.impl;

import com.yanfan.common.core.domain.AjaxResult;
import com.yanfan.common.utils.SecurityUtils;
import com.yanfan.energy.domain.Common;
import com.yanfan.energy.domain.EquipmentConsumption;
import com.yanfan.energy.domain.EquipmentConsumptionDto;
import com.yanfan.energy.domain.PurchasingEnergy;
import com.yanfan.energy.mapper.EquipmentConsumptionDao;
import com.yanfan.energy.service.EquipmentConsumptionService;
import com.yanfan.energy.util.DateUtils;
import com.yanfan.energy.util.DoubleOperation;
import com.yanfan.iot.domain.Device;
import com.yanfan.iot.mapper.DeviceMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 设备能耗表(EquipmentConsumption)表服务实现类
 *
 * @author makejava
 * @since 2022-10-11 18:16:45
 */
@Service("equipmentConsumptionService")
@Transactional
public class EquipmentConsumptionServiceImpl implements EquipmentConsumptionService {
    @Autowired
    private EquipmentConsumptionDao equipmentConsumptionDao;

    @Autowired
    private DeviceMapper deviceMapper;

    @Override
    public AjaxResult selectequipmentEnergy(Long buildingId, List<Integer> workshopIds, List<Integer> deviceIds, Integer classifyId, String deviceName, String begin, String end) {
        List<EquipmentConsumptionDto> equipmentConsumptionDtos = new ArrayList<>();
        //设备id不为空
        if (deviceIds != null && deviceIds.size() > 0) {
            deviceIds.stream().forEach(e -> {
                equipmentConsumptionDtos.containsAll(equipmentConsumptionDao.selectequipmentEnergyBydeviceId(e.longValue()));
            });
            //车间id不为空
        } else if (workshopIds != null && workshopIds.size() > 0) {
            workshopIds.stream().forEach(e -> {
                equipmentConsumptionDtos.containsAll(equipmentConsumptionDao.selectequipmentEnergyByworkshopId(e.longValue()));
            });
            //查询楼栋
        } else if (!StringUtils.isEmpty(buildingId)) {
            return AjaxResult.success(new PageInfo<>(equipmentConsumptionDao.selectequipmentEnergyBybuildingId(buildingId)));
        } else {
            return AjaxResult.success(new PageInfo<>(equipmentConsumptionDao.selectequipmentEnergy()));
        }


        return AjaxResult.success(new PageInfo<>(equipmentConsumptionDtos));
    }

    @Override
    public void deleteByCreatdateandEquipment(String time, String id) {
        equipmentConsumptionDao.deleteByCreatdateandEquipment(time, id);
    }

    /**
     * 能源采购新增
     *
     * @param purchasingEnergy
     * @return
     */
    @Override
    public AjaxResult addPurchase(PurchasingEnergy purchasingEnergy) {
        if (!Objects.isNull(purchasingEnergy)) {
            purchasingEnergy.setPurchaseDates(DateUtils.parseDate(purchasingEnergy.getPurchaseDate()));
            // 获取用户名
            purchasingEnergy.setCreatedBy(SecurityUtils.getUsername());
            purchasingEnergy.setCreatedUser(SecurityUtils.getUserId());// 用户id 用来关联组织  （暂时解决办法 后续可能会删除）
            // 获取当前登陆用户二级部门 ID
            purchasingEnergy.setAncestor(getAncestor());
            int i = equipmentConsumptionDao.addPurchase(purchasingEnergy);
            if (i > 0) {
                return AjaxResult.success("新增成功");
            }
        }
        return AjaxResult.error("新增失败");
    }

    private String getAncestor() {
        String ancestors = equipmentConsumptionDao.selectDeptAncestors(SecurityUtils.getUserId());
        if (ancestors.contains("100,")) { // 本部门是不是二级部门
            String[] split = ancestors.split(",");
            return split[2];
        } else {
            return String.valueOf(SecurityUtils.getDeptId());
        }
    }

    /**
     * 能源采购删除
     *
     * @param id
     * @return
     */
    @Override
    public AjaxResult deletePurchase(Integer id) {
        int i = equipmentConsumptionDao.deletePurchase(id);
        if (i > 0) {
            return AjaxResult.success("删除成功");
        }
        return AjaxResult.error("删除失败");
    }

    /**
     * 能源采购更新
     *
     * @param purchasingEnergy
     * @return
     */
    @Override
    public AjaxResult updatePurchase(PurchasingEnergy purchasingEnergy) {
        if (Objects.isNull(purchasingEnergy)) {
            return AjaxResult.error("入参为空");
        }
        if (Objects.isNull(purchasingEnergy.getType())) {
            if (purchasingEnergy.getType() == 1) {
                purchasingEnergy.setTypeName("冷却水");
            }
            if (purchasingEnergy.getType() == 2) {
                purchasingEnergy.setTypeName("软化水");
            }
            if (purchasingEnergy.getType() == 4) {
                purchasingEnergy.setTypeName("压缩空气");
            }
            if (purchasingEnergy.getType() == 5) {
                purchasingEnergy.setTypeName("天然气");
            }
            if (purchasingEnergy.getType() == 6) {
                purchasingEnergy.setTypeName("蒸汽");
            }
            if (purchasingEnergy.getType() == 7) {
                purchasingEnergy.setTypeName("尖电");
            }
            if (purchasingEnergy.getType() == 8) {
                purchasingEnergy.setTypeName("峰电");
            }
            if (purchasingEnergy.getType() == 9) {
                purchasingEnergy.setTypeName("平电");
            }
            if (purchasingEnergy.getType() == 10) {
                purchasingEnergy.setTypeName("谷电");
            }
        }
        purchasingEnergy.setPurchaseDates(DateUtils.parseDate(purchasingEnergy.getPurchaseDate()));
        int i = equipmentConsumptionDao.updatePurchase(purchasingEnergy);
        if (i > 0) {
            return AjaxResult.success("更新成功");
        }
        return AjaxResult.error("更新失败");
    }

    /**
     * 能源采购列表查看
     *
     * @param type
     * @param begin
     * @param end
     * @param currPage
     * @param pageSize
     * @return
     */
    @Override
    public AjaxResult purchase(String type, String begin, String end, int currPage, int pageSize) {
        PageHelper.startPage(currPage, pageSize);
        List<PurchasingEnergy> purchase = equipmentConsumptionDao.purchase(begin, end);
        purchase.stream().forEach(p -> {
            if (p.getType() == 1) {
                p.setTypeName("冷却水");
            }
            if (p.getType() == 2) {
                p.setTypeName("软化水");
            }
            if (p.getType() == 4) {
                p.setTypeName("压缩空气");
            }
            if (p.getType() == 5) {
                p.setTypeName("天然气");
            }
            if (p.getType() == 6) {
                p.setTypeName("蒸汽");
            }
            if (p.getType() == 7) {
                p.setTypeName("尖电");
            }
            if (p.getType() == 8) {
                p.setTypeName("峰电");
            }
            if (p.getType() == 9) {
                p.setTypeName("平电");
            }
            if (p.getType() == 10) {
                p.setTypeName("谷电");
            }
            if (p.getType() == 11) {
                p.setTypeName("压缩空气");
            }
            if (p.getType() == 12) {
                p.setTypeName("煤");
            }
            if (p.getType() == 13) {
                p.setTypeName("一氧化碳");
            }
            if (p.getType() == 14) {
                p.setTypeName("二氧化碳");
            }
            if (p.getType() == 15) {
                p.setTypeName("纯氧");
            }

        });
        if (!Objects.isNull(type)) {
            return AjaxResult.success(new PageInfo<>(purchase
                                                             .stream()
                                                             .filter(s -> !s.getType().equals(type))
                                                             .collect(Collectors.toList())));
        }
        if (purchase != null && purchase.size() > 0) {
            return AjaxResult.success(new PageInfo<>(purchase));
        }
        return AjaxResult.success(new PageInfo<>(purchase));
    }

    @Override
    public List<PurchasingEnergy> findAllPurchase(String name, LocalDate begin, LocalDate end) {
        Date beginDate = DateUtils.parseDate(begin);
        Date endDate = DateUtils.parseDate(end);
        if (!StringUtils.isEmpty(name)) {
            name = "%" + name + "%";
        }
        return equipmentConsumptionDao.findAllPurchase(name, beginDate, endDate);
    }

    /**
     * 采购金额统计 ,移动端采购金额统计 接口
     *
     * @return
     */
    @Override
    public AjaxResult purchaseMoneyStat() {

        List<PurchasingEnergy> purchaseList = equipmentConsumptionDao.findAllPurchase(Strings.EMPTY, DateUtils.getPreYearPreMon(1, 0), DateUtils.getNowDate());
        if (purchaseList == null || purchaseList.isEmpty()) {
            return AjaxResult.success("无数据");
        }
        Map<String, Double> purchaseMap = new HashMap<>();
        Map<String, Object> resMap = new HashMap<>();
        // 总价格
        resMap.put("totalMoney", 0.0);
        purchaseList.forEach(purchase -> purchaseListTrans(purchaseMap, purchase, resMap));
        // 平均价格  divide
        resMap.put("avgMoney", DoubleOperation.divide((Double) resMap.get("totalMoney"), (double) purchaseList.size()));
        // 查询上个月、上上个月、去年的上个月（比如 2022-11-22  找2021-11）
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        String preMon = format.format(DateUtils.getPreMon(1));
        String prePreMon = format.format(DateUtils.getPreMon(2));
        String preYearPreMon = format.format(DateUtils.getPreYearPreMon(1, 1));
        Map<String, Double> sumPurchaseMap = new HashMap();
        sumPurchaseMap.put(preMon, null);
        sumPurchaseMap.put(prePreMon, null);
        sumPurchaseMap.put(preYearPreMon, null);
        // 上个月
        List<PurchasingEnergy> purchaseListByMonths = equipmentConsumptionDao.findAllPurchaseList();
        purchaseListByMonths.forEach(pur -> transPurchaseMap(sumPurchaseMap, pur));
        // 同比  （本月－上年度的本月）/上年度的本月*100％
        resMap.put("onYearBasis", DoubleOperation.divide(DoubleOperation.subNull(sumPurchaseMap.get(preMon), sumPurchaseMap.get(preYearPreMon)), sumPurchaseMap.get(preYearPreMon)));
        // 环比指的是当前月与上个月比值（本月－上个月）/上个月*100％。
        resMap.put("chainRelative", DoubleOperation.divide(DoubleOperation.subNull(sumPurchaseMap.get(preMon), sumPurchaseMap.get(prePreMon)), sumPurchaseMap.get(prePreMon)));
        resMap.put("chart", purchaseMap);
        return AjaxResult.success(resMap);
    }

    private void transPurchaseMap(Map map, PurchasingEnergy pur) {
        String date = pur.getPurchaseDate().substring(5, 7);
        if (!map.containsKey(date)) {
            return;
        }
        if (map.get(date) == null) {
            map.put(date, pur.getCountPrice());
        } else {
            map.put(date, DoubleOperation.add(pur.getCountPrice(), (Double) map.get(date)));
        }
    }


    private void purchaseListTrans(Map<String, Double> purchaseMap, PurchasingEnergy purchase, Map<String, Object> resMap) {
        // 根据采购时间区分  purchaseDate 年-月
        String purchaseDate = purchase.getPurchaseDate();
        if (StringUtils.isEmpty(purchase) || purchase.getCountPrice() == null) {
            return;
        }
        String keyDate = purchaseDate.substring(5, 7);
        // 能耗采购管理（累计采购金额）
        resMap.put("totalMoney", DoubleOperation.add((Double) resMap.get("totalMoney"), purchase.getCountPrice()));
        if (purchaseMap.get(keyDate) == null) {
            purchaseMap.put(keyDate, purchase.getCountPrice());
        } else {
            purchaseMap.put(keyDate, DoubleOperation.add(purchaseMap.get(keyDate), purchase.getCountPrice()));
        }
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public EquipmentConsumption queryById(Integer id) {
        return this.equipmentConsumptionDao.queryById(id);
    }

    /**
     * 分页查询
     *
     * @param equipmentConsumption 筛选条件
     * @param pageRequest          分页对象
     * @return 查询结果
     */
    @Override
    public Page<EquipmentConsumption> queryByPage(EquipmentConsumption equipmentConsumption, PageRequest pageRequest) {
        long total = this.equipmentConsumptionDao.count(equipmentConsumption);
        return new PageImpl<>(this.equipmentConsumptionDao.queryAllByLimit(equipmentConsumption, pageRequest), pageRequest, total);
    }

    /**
     * 新增数据
     *
     * @param equipmentConsumption 实例对象
     * @return 实例对象
     */
    @Override
    public EquipmentConsumption insert(EquipmentConsumption equipmentConsumption) {
        this.equipmentConsumptionDao.insert(equipmentConsumption);
        return equipmentConsumption;
    }

    /**
     * 修改数据
     *
     * @param equipmentConsumption 实例对象
     * @return 实例对象
     */
    @Override
    public EquipmentConsumption update(EquipmentConsumption equipmentConsumption) {
        this.equipmentConsumptionDao.update(equipmentConsumption);
        return this.queryById(equipmentConsumption.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.equipmentConsumptionDao.deleteById(id) > 0;
    }

    @Override
    public EquipmentConsumption selectequipmentConsumptionOrderBycreatedDateLimit() {
        return this.equipmentConsumptionDao.selectequipmentConsumptionOrderBycreatedDateLimit();
    }

    @Override
    public EquipmentConsumption selectequipmentConsumptionAndDeviceOrderBycreatedDateLimit() {
        return this.equipmentConsumptionDao.selectequipmentConsumptionAndDeviceOrderBycreatedDateLimit();
    }

    @Override
    public List<EquipmentConsumption> selectOneyly() {
        return this.equipmentConsumptionDao.selectOneyly();
    }

    @Override
    public AjaxResult selectenquipmentConsumptionBycondition() {
        //查询所有设备
        List<Device> devices = deviceMapper.selectDeviceList(new Device());
        Map map = new HashMap();
        //按设备id查询每小时
        devices.stream().forEach(e -> {
            List<Common> commons = this.equipmentConsumptionDao.selectenquipmentConsumptionBycondition(e.getDeviceId());
            map.put(e.getDeviceName(), commons);
        });
        return AjaxResult.success(map);
    }


}
